﻿using System;
using System.Windows.Controls;
using System.Windows.Media.Imaging;
using Plugins;
using StockAccessors;
using StockModel;
using Utils;

[assembly: PluginContainerAssembly]

namespace FullDayStrategyPlugin
{
	public class FullDayStrategyPlugin2 : IStrategyPlugin
	{
		#region Attributes

		private Historical.ControlPanel _historicalControlPanel;
		private Realtime.ControlPanel _realtimeControlPanel;
		private VisualRepresentation _visualRepresentation;

		private Realtime.Engine _realtimeEngine;
		private Historical.Engine _historicalEngine;

		private DecisionEngineDataSource _decisionEngineDataSource;
		private DecisionEngineData _decisionEngineData;

		#endregion

		#region Properties

		public VisualRepresentation VisualRepresentation
		{
			get
			{
				return _visualRepresentation;
			}
		}

		public UserControl HistoricalControlPanel
		{
			get
			{
				return _historicalControlPanel;
			}
		}

		public UserControl RealtimeControlPanel
		{
			get
			{
				return _realtimeControlPanel;
			}
		}

		public bool SupportsRealtime
		{
			get
			{
				return true;
			}
		}

		#endregion

		#region Events

		public event EventHandler<HistoricalResultsAvailableEventArgs> HistoricalResultsAvailable;
		public event EventHandler<RealtimeNotificationEventArgs> RealtimeNotification;

		#endregion

		#region Public Methods

		public void Initialize(SqlDataBaseClient databaseClient, QuotationDataSource quotationDataSource, ExchangeMarketDataSource exchangeMarketDataSource, RawStockDataSource rawStockDataSource, ObservableCollection2<StockGroup> groups, IOrderExecutor executor, IStockDataAccessorInformation accessorInformation)
		{
			_visualRepresentation = new VisualRepresentation(new BitmapImage(new Uri(@"pack://application:,,,/FullDayStrategyPlugin2;component/Resources/ToolBar.ico")), "Full Day Strategy 2");

			DailyChartGenerator dailyChartGenerator = new DailyChartGenerator();

			DecisionEngineData historicalEngineData = new DecisionEngineData();
			_historicalEngine = new Historical.Engine(quotationDataSource, rawStockDataSource, dailyChartGenerator, historicalEngineData);

			_historicalControlPanel = new Historical.ControlPanel();
			_historicalControlPanel.DataContext = new Historical.ControlPanelVM(rawStockDataSource, _historicalEngine, quotationDataSource);

			_historicalEngine.ResultsAvailable += HistoricalEngine_ResultsAvailable; // Local object

			_historicalControlPanel.SizeChanged += (sender, args) => // Local object
			{
				dailyChartGenerator.ImageWidth = ((Historical.ControlPanel)sender).ActualWidth * 0.95;
			};

			_decisionEngineDataSource = new DecisionEngineDataSource();
			_decisionEngineData = new DecisionEngineData();

			_realtimeEngine = new Realtime.Engine(executor, groups, _decisionEngineData, accessorInformation);
			_realtimeControlPanel = new Realtime.ControlPanel();
			_realtimeControlPanel.DataContext = new Realtime.ControlPanelVM(rawStockDataSource, _realtimeEngine, _decisionEngineData, _decisionEngineDataSource);

			_realtimeEngine.RealtimeNotification += RealtimeEngine_RealtimeNotification; // Local object
		}

		protected virtual void OnResultsAvailable(HistoricalResultsAvailableEventArgs e)
		{
			if (this.HistoricalResultsAvailable != null)
			{
				this.HistoricalResultsAvailable(this, e);
			}
		}

		protected virtual void OnRealtimeNotification(RealtimeNotificationEventArgs e)
		{
			if (this.RealtimeNotification != null)
			{
				this.RealtimeNotification(this, e);
			}
		}

		#endregion

		#region Event Handlers
		// ReSharper disable InconsistentNaming

		private void HistoricalEngine_ResultsAvailable(object sender, HistoricalResultsAvailableEventArgs e)
		{
			this.OnResultsAvailable(e);
		}

		private void RealtimeEngine_RealtimeNotification(object sender, RealtimeNotificationEventArgs e)
		{
			this.OnRealtimeNotification(e);
		}

		// ReSharper restore InconsistentNaming
		#endregion

		#region IDisposable

		protected bool Disposed { get; private set; }

		private void Dispose(bool disposing)
		{
			if (!this.Disposed)
			{
				this.InternalDispose(disposing);
			}

			this.Disposed = true;
		}

		protected virtual void InternalDispose(bool disposing)
		{
			if (disposing)
			{
				if (_realtimeControlPanel != null)
				{
					_realtimeControlPanel.DataContext.Dispose();
				}
				if (_realtimeEngine != null)
				{
					_realtimeEngine.Dispose();
				}
				if (_historicalEngine != null)
				{
					_historicalEngine.Dispose();
				}
			}

			// Dispose here only unmanaged objects 
			// Don’t use managed objects here because maybe 
			// they have been finalized already
		}

		public void Dispose()
		{
			this.Dispose(true);
			GC.SuppressFinalize(this);
		}

		~FullDayStrategyPlugin2()
		{
			this.Dispose(false);
		}

		#endregion
	}
}
